#include "joystickwidget.h"

#include <math.h>
#include <QtMath>

//弧度转角度
#define PI 3.1415926
#define r2a(x) (x/PI*180)

JoystickWidget::JoystickWidget(QWidget *parent)
    : QWidget(parent)
{
    InitUI();
    createConnection();


    m_curDirection =  D_stop;
}

JoystickWidget::~JoystickWidget()
{

}

void JoystickWidget::resizeEvent(QResizeEvent *event)
{
    Q_UNUSED(event);
    ResetCenterOfCircle();
}


void JoystickWidget::InitUI()
{
    this->setWindowFlags(Qt::FramelessWindowHint);

    //设置窗口固定大小为400*400
    this->setFixedSize(300,300);
    //this->setMinimumSize(500,500);

    ResetCenterOfCircle();
    //鼠标点击标志初始化
    MousePressFlag=false;

    //初始化遥杆path
    InitCirclePath();

}

void JoystickWidget::InitCirclePath()
{
    m_vecPath.resize(9);
    QPoint center =BigCir_xy;
    int segments = 8;
    double angleStep = 360.0 / segments;

    double startAngle = 22.5;

    for (int i = 0; i < segments; ++i) {
        // 计算当前扇形的起始和结束角度

        double endAngle = startAngle + angleStep;

        // 创建路径绘制扇形

        QPainterPath path;

        QPointF startPoint(
                    center.x() + (BIG_CIRCLE_RADIUS / 2) * cos(qDegreesToRadians(startAngle)),
                    center.y() - (BIG_CIRCLE_RADIUS / 2) * sin(qDegreesToRadians(startAngle)) //QT y的正方向时向下，我看作向上，所以用 减法
                    );

        path.moveTo(startPoint);

        path.arcTo(
                    center.x() - BIG_CIRCLE_RADIUS/2,
                    center.y() - BIG_CIRCLE_RADIUS/2,
                    BIG_CIRCLE_RADIUS, BIG_CIRCLE_RADIUS,
                    startAngle, angleStep
                    );

        path.arcTo(
                    center.x() - BIG_CIRCLE_RADIUS,
                    center.y() - BIG_CIRCLE_RADIUS,
                    2* BIG_CIRCLE_RADIUS, 2 *BIG_CIRCLE_RADIUS,
                    startAngle + angleStep ,-angleStep
                    );


        path.closeSubpath();
        startAngle = endAngle;


        switch (i){
        case 0:
        {
            m_vecPath[D_forward_right] = path;
            break;
        }
        case 1:
        {
            m_vecPath[D_forward] = path;
            break;
        }
        case 2:
        {
            m_vecPath[D_forward_left] = path;
            break;
        }
        case 3:
        {
            m_vecPath[D_turn_left] = path;
            break;
        }
        case 4:
        {
            m_vecPath[D_bck_left] = path;
            break;
        }
        case 5:
        {
            m_vecPath[D_back] = path;
            break;
        }
        case 6:
        {
            m_vecPath[D_back_right] = path;
            break;
        }
        case 7:
        {
            m_vecPath[D_trun_right] = path;
            break;
        }
        default:{
            break;
        }
        }
    }
}

void JoystickWidget::ResetCenterOfCircle()
{
    //设置大圆圆心位置
    SmallCir_xy.setX(this->width()/2);
    SmallCir_xy.setY(this->height()/2);
    //设置小圆圆心位置，与大圆相同
    BigCir_xy=SmallCir_xy;

}

void JoystickWidget::createConnection()
{
    connect(this, &JoystickWidget::sigDirection, this, &JoystickWidget::onDirection);
}

//绘图事件：绘制地图、摇杆中的大圆和小圆
void JoystickWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    //绘图画笔
    QPainter painter(this);
    //抗锯齿
    painter.setRenderHint(QPainter::Antialiasing, true);
    //消锯齿
    painter.setRenderHints(QPainter::SmoothPixmapTransform);

    //大圆
    QBrush brush(Qt::darkGray);
    painter.setBrush(brush);
    painter.drawEllipse(BigCir_xy,BIG_CIRCLE_RADIUS,BIG_CIRCLE_RADIUS);

    //中间再画一个圆吧
    brush.setColor(Qt::white);
    painter.setBrush(brush);
    painter.drawEllipse(BigCir_xy,BIG_CIRCLE_RADIUS/2,BIG_CIRCLE_RADIUS/2);


    QPoint center =BigCir_xy;

    // 绘制外圆
    painter.setPen(Qt::black);
    painter.setBrush(Qt::NoBrush);
    //painter.drawEllipse(center, diameter / 2, diameter / 2);

    for(unsigned int i =1; i < m_vecPath.size(); i++)
    {
        painter.drawPath(m_vecPath[i]);
    }

    if(m_curDirection !=  D_stop)
    {    brush.setColor(Qt::black);
        painter.setBrush(brush);
        painter.drawPath(m_vecPath[m_curDirection]);
    }

    //小圆直径
    int diameter = 2*SMALL_CIRCLE_RADIUS;

    // 创建渐变色
    QRadialGradient radialGrad(SmallCir_xy, diameter/2, SmallCir_xy);
    radialGrad.setColorAt(0.0, QColor(255, 0, 0));
    radialGrad.setColorAt(0.7, QColor(200, 50, 50));
    radialGrad.setColorAt(1.0, QColor(200, 200, 200));


    painter.setBrush(radialGrad);
    painter.setPen(Qt::NoPen);
    painter.drawEllipse(SmallCir_xy, diameter/2, diameter/2);


    painter.save();
}

//鼠标移动事件：实现摇杆功能
void JoystickWidget::mouseMoveEvent(QMouseEvent *e)
{
    QPoint rocker_xy; //摇杆所在的实时坐标
    QByteArray xy;
    xy.resize(2);
    int x,y;
    rocker_xy=e->pos();

    if(MousePressFlag) //MousePressFlag为true，说明鼠标点击在了大圆内，才进行计算
    {

        double arc2 = atan2(BigCir_xy.y() - rocker_xy.y(),rocker_xy.x()-BigCir_xy.x());

        //小圆圆心出了大圆边界

        if(pow((rocker_xy.x()-BigCir_xy.x()),2)+pow((rocker_xy.y()-BigCir_xy.y()),2)>pow(BIG_CIRCLE_RADIUS,2))
        {
            //atan2(y, x)则用于计算坐标系中由原点指向(y, x)点的射线与x轴正方向之间的角度，返回值范围为[-π, π]
            double arc = atan2(abs(rocker_xy.y()-BigCir_xy.y()),abs(rocker_xy.x()-BigCir_xy.x()));
            x=int( BIG_CIRCLE_RADIUS*cos(arc) );
            y=int( BIG_CIRCLE_RADIUS*sin(arc) );

            //第一象限
            if(rocker_xy.x()>BigCir_xy.x()&&rocker_xy.y()>BigCir_xy.y())
            {
                SmallCir_xy.setX(x+BigCir_xy.x());
                SmallCir_xy.setY(y+BigCir_xy.y());
            }
            //第二象限
            else if(rocker_xy.x()<BigCir_xy.x()&&rocker_xy.y()>BigCir_xy.y())
            {
                SmallCir_xy.setX(-x+BigCir_xy.x());
                SmallCir_xy.setY(y+BigCir_xy.y());
                x=-x;
            }
            //第三象限
            else if(rocker_xy.x()<BigCir_xy.x()&&rocker_xy.y()<BigCir_xy.y())
            {
                SmallCir_xy.setX(-x+BigCir_xy.x());
                SmallCir_xy.setY(-y+BigCir_xy.y());
                x=-x;
                y=-y;
            }
            //第四象限
            else if(rocker_xy.x()>BigCir_xy.x()&&rocker_xy.y()<BigCir_xy.y())
            {
                SmallCir_xy.setX(x+BigCir_xy.x());
                SmallCir_xy.setY(-y+BigCir_xy.y());
                y=-y;
            }
        }
        else
        {
            x=rocker_xy.x()-BigCir_xy.x();
            y=rocker_xy.y()-BigCir_xy.y();
            SmallCir_xy=rocker_xy;
        }

        //圆心进入半圆之内，才执行操作
        if(pow((rocker_xy.x()-BigCir_xy.x()),2)+pow((rocker_xy.y()-BigCir_xy.y()),2)>pow(BIG_CIRCLE_RADIUS/2,2))
        {

            double curDegree = r2a(arc2);//转化为360吧
            if(curDegree <0)
            {
                curDegree += 360;
            }
            double div = 360 /16;
            double startDegree = div;

            m_curDirection = Direction::D_Invalid;
            if(curDegree >= startDegree && curDegree < startDegree+div*2)
            {
                m_curDirection = Direction::D_forward_right;
            }
            else if(curDegree >= startDegree + div*2 && curDegree< startDegree+div*4)
            {
                m_curDirection = Direction::D_forward;
            }
            else if(curDegree >=  startDegree+div*4 && curDegree< startDegree+div*6)
            {
                m_curDirection = Direction::D_forward_left;
            }
            else if(curDegree >=  startDegree+div*6 && curDegree< startDegree+div*8)
            {
                m_curDirection = Direction::D_turn_left;
            }
            else if(curDegree >=  startDegree+div*8 && curDegree< startDegree+div*10)
            {
                m_curDirection = Direction::D_bck_left;
            }else if(curDegree >=  startDegree+div*10 && curDegree< startDegree+div*12)
            {
                m_curDirection = Direction::D_back;
            }
            else if(curDegree >=  startDegree+div*12 && curDegree< startDegree+div*14)
            {
                m_curDirection = Direction::D_back_right;
            }
            else if((curDegree>=startDegree+div*14 && curDegree<=360) || (curDegree>=0 &&  curDegree<startDegree))
            {
                m_curDirection = Direction::D_trun_right;
            }

            if(m_curDirection != Direction::D_Invalid)
            {
                emit sigDirection(m_curDirection);
            }

            qDebug() << "curDegree:" << curDegree  <<  " arg:" << arc2 << "direction:" << m_curDirection <<  endl;
        }

        update();
    }

    MapRemov_Old=rocker_xy;
}

//鼠标释放事件：释放鼠标，则MousePressFlag复位，且小圆圆心设置为初始值，更新绘图事件后，重新绘图使小圆（摇杆）回到原处
void JoystickWidget::mouseReleaseEvent(QMouseEvent *e)
{
    Q_UNUSED(e);

    MousePressFlag=false;
    m_curDirection = D_stop;//复位状态
    emit sigDirection(m_curDirection); // 发送停止信号
    ResetCenterOfCircle();
    this->update(); //更新绘图事件后，重新绘图使小圆（摇杆）回到原处
}

void JoystickWidget::onDirection(Direction d)
{

}

//鼠标按下事件：获取摇杆所在的实时坐标
void JoystickWidget::mousePressEvent(QMouseEvent *e)
{
    QPoint rocker_xy; //摇杆所在的实时坐标

    rocker_xy=e->pos(); //获取摇杆所在的实时坐标
    qDebug() <<"摇杆坐标： " <<rocker_xy;

    //鼠标点击，在大圆内才设置MousePressFlag
    if(pow((rocker_xy.x()-SmallCir_xy.x()),2)+pow((rocker_xy.y()-SmallCir_xy.y()),2)<=pow(BIG_CIRCLE_RADIUS,2)) //判断摇杆是否在大圆内
    {
        MousePressFlag=true;
    }
    else
    {
        MapRemov_Old=rocker_xy;
    }
}
